import pandas as pd
import re
import statsmodels.api as sm
import matplotlib.pyplot as plt
import seaborn as sns

# 设置中文字体显示（如果需要显示中文）
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei', 'SimHei']
plt.rcParams['axes.unicode_minus'] = False


# 1. 读取数据
file_path = "附件.xlsx"
male_df = pd.read_excel(file_path, sheet_name="男胎检测数据")

# 2. 将孕周数转为小数形式（周+天 -> 小数周数）
def parse_gestation(week_str):
    if isinstance(week_str, str):
        match = re.match(r"(\d+)w\+(\d+)", week_str)
        if match:
            weeks = int(match.group(1))
            days = int(match.group(2))
            return weeks + days / 7
    return None

#对 DataFrame male_df 中的 "检测孕周" 列进行数据转换，并将转换后的结果存储到新列
male_df["孕周数"] = male_df["检测孕周"].apply(parse_gestation)

# 3. 提取需要的变量
#从 DataFrame male_df 中筛选出指定列，并删除包含缺失值（NaN）的行
data = male_df[["孕周数", "孕妇BMI", "Y染色体浓度"]].dropna()

# 4. 多元线性回归
X = data[["孕周数", "孕妇BMI"]]
y = data["Y染色体浓度"]

# 添加常数项
X = sm.add_constant(X)

# 创建OLS模型并拟合数据, 输出模型统计摘要
model = sm.OLS(y, X).fit()
print(model.summary())

# 5. 绘图：散点图 + 回归拟合
plt.figure(figsize=(10,5))
sns.scatterplot(x="孕周数", y="Y染色体浓度", data=data, alpha=0.6, label="样本点")
sns.regplot(x="孕周数", y="Y染色体浓度", data=data, scatter=False, color="red", label="拟合线")
plt.xlabel("孕周数（周）")
plt.ylabel("Y染色体浓度")
plt.title("孕周数与Y染色体浓度的关系")
plt.legend()
plt.savefig('figure1.png')  # 保存图像
plt.close()  # 关闭图形

# 6. 残差分析
residuals = model.resid #获取残差
plt.figure(figsize=(8,5))
sns.histplot(residuals, kde=True) # 绘制残差分布
plt.xlabel("残差值")
plt.title("回归残差分布")
plt.savefig('figure2.png')  # 保存图像
plt.close()  # 关闭图形

#创建图形窗口
plt.figure(figsize=(8,5))
#绘制散点图
plt.scatter(model.fittedvalues, residuals, alpha=0.6)
#添加参考线
plt.axhline(y=0, color="red", linestyle="--")
plt.xlabel("拟合值")
plt.ylabel("残差")
plt.title("残差与拟合值关系")
plt.savefig('figure3.png')  # 保存图像
plt.close()  # 关闭图形

print("图表已保存为 figure1.png, figure2.png 和 figure3.png")



